package org.eclipse.pde.toolbox.adaptors.view;

import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.InputDialog;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.jface.viewers.ViewerSorter;
import org.eclipse.pde.toolbox.Activator;
import org.eclipse.pde.toolbox.adaptors.internal.AdaptorLeaf;
import org.eclipse.pde.toolbox.adaptors.internal.AdaptorRoot;
import org.eclipse.pde.toolbox.adaptors.internal.FactoryRoot;
import org.eclipse.pde.toolbox.adaptors.internal.IRoot;
import org.eclipse.pde.toolbox.adaptors.internal.ITreeNode;
import org.eclipse.pde.toolbox.adaptors.internal.NamespaceRoot;
import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.Clipboard;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.dialogs.PatternFilter;
import org.eclipse.ui.part.DrillDownAdapter;
import org.eclipse.ui.part.ViewPart;


public class AdaptorView extends ViewPart {

	private TreeViewer viewer;
	private DrillDownAdapter drillDownAdapter;

	private class AdaptorSorter extends ViewerSorter {
		public int category(Object element) {
			if (element instanceof AdaptorLeaf) {
				return 0;
			}
			return 1;
		}
	}

	private void contributeToActionBars() {
		IActionBars bars = getViewSite().getActionBars();

		// bars.getMenuManager()
		IMenuManager manager = bars.getMenuManager();
		manager.add(new Separator());
		manager.add(filterAction);
		manager.add(hideEmpty);
		manager.add(new Separator());

		manager.add(pluginView);
		manager.add(factoryAdapter);
		manager.add(adaptorFactory);

		manager.add(new Separator());

		drillDownAdapter.addNavigationActions(manager);
		manager.add(new Separator());

		// bars.getToolBarManager()
		IToolBarManager toolBarManager = bars.getToolBarManager();
		drillDownAdapter.addNavigationActions(toolBarManager);

		toolBarManager.add(new Separator());
		toolBarManager.add(pluginView);
		toolBarManager.add(factoryAdapter);
		toolBarManager.add(adaptorFactory);

		toolBarManager.add(new Separator());

		toolBarManager.add(filterAction);
		toolBarManager.add(hideEmpty);
		toolBarManager.add(new Separator());

	}

	private void hookContextMenu() {
		MenuManager menuMgr = new MenuManager("#PopupMenu");
		menuMgr.setRemoveAllWhenShown(true);
		menuMgr.addMenuListener(new IMenuListener() {
			public void menuAboutToShow(IMenuManager manager) {
				AdaptorView.this.fillContextMenu(manager);
			}
		});

		Menu menu = menuMgr.createContextMenu(viewer.getControl());
		viewer.getControl().setMenu(menu);
		getSite().registerContextMenu(menuMgr, viewer);
	}

	/**
	 * adaug actiuni la contextMenu->(clickDreapta)
	 * */
	private void fillContextMenu(IMenuManager manager) {
		drillDownAdapter.addNavigationActions(manager);
		manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
		manager.add(copyAction);
	}

	private IAction filterAction;
	private IAction factoryAdapter;
	private IAction hideEmpty;
	private IAction adaptorFactory;
	private IAction pluginView;
	private IAction copyAction;

	private PatternFilter patternFilter = new PatternFilter() {
		public boolean isElementVisible(Viewer viewer, Object element) {
			if (FactoryRoot.instance.isTopLevelElement(element)) {
				return wordMatches(element.toString());
			}
			if (AdaptorRoot.instance.isTopLevelElement(element)) {
				return wordMatches(element.toString());
			}
			if (NamespaceRoot.instance.isTopLevelElement(element))
				return wordMatches(element.toString());
			return true;
		}
	};

	private final ViewerFilter viewerFilter = new ViewerFilter() {
		public boolean select(Viewer viewer, Object parentElement,
				Object element) {
			if (parentElement instanceof IRoot) {
				return ((ITreeNode) element).hasChildren();
			}
			return true;
		}
	};

	private void makeActions() {

		copyAction = new Action("copy", Activator
				.getImageDescriptor("icon/somethig.jpg")) {
			public void run() {
				String info = "";
				StructuredSelection selection = (StructuredSelection) viewer
						.getSelection();
				Object obj = selection.getFirstElement();
				if (obj instanceof ITreeNode) {
					info = ((ITreeNode) obj).getDescription();
//					System.out.println("object=" + info);
				}

				Clipboard cb = new Clipboard(Display.getDefault());
				TextTransfer textTransfer = TextTransfer.getInstance();
				cb.setContents(new Object[] { info },
						new TextTransfer[] { textTransfer });
			}
		};
		
//		copyAction.setAccelerator();
		
		
		pluginView = new Action("plugin", IAction.AS_RADIO_BUTTON) {
			public void run() {
				viewer.setInput(NamespaceRoot.instance);
			}
		};
		pluginView.setToolTipText("plugin view");
		pluginView.setImageDescriptor(Activator
				.getImageDescriptor("icon/plugin.jpg"));

		hideEmpty = new Action("hide empty", IAction.AS_CHECK_BOX) {
			public void run() {
				viewer.getTree().setRedraw(false);
				try {
					if (this.isChecked())
						viewer.addFilter(viewerFilter);
					else
						viewer.removeFilter(viewerFilter);
				} finally {
					viewer.getTree().setRedraw(true);
				}
			}
		};
		hideEmpty.setToolTipText("hide empty top level elements");
		hideEmpty.setImageDescriptor(Activator
				.getImageDescriptor("icon/hideempty.jpg"));

		filterAction = new Action("filter...", Activator
				.getImageDescriptor("icon/filter.jpg")) {
			private String pattern = "";

			public void run() {
				InputDialog dialog = new InputDialog(getSite().getShell(),
						"Apply text filter...",
						"Input pattern (* and ? work):", pattern, null);
				if (dialog.open() == Dialog.OK) {
					viewer.getTree().setRedraw(false);
					try {
						pattern = dialog.getValue();
						patternFilter.setPattern(pattern);
						viewer.removeFilter(patternFilter);
						viewer.addFilter(patternFilter);
					} finally {
						viewer.getTree().setRedraw(true);
					}
				}
			}
		};

		factoryAdapter = new Action("Factory", IAction.AS_RADIO_BUTTON) {

			public void run() {
				viewer.setInput(FactoryRoot.instance);
			}
		};
		factoryAdapter.setImageDescriptor(Activator
				.getImageDescriptor("icon/factory.jpg"));

		adaptorFactory = new Action("Adaptor", IAction.AS_RADIO_BUTTON) {

			public void run() {
				viewer.setInput(AdaptorRoot.instance);
			}
		};
		adaptorFactory.setImageDescriptor(Activator
				.getImageDescriptor("icon/adaptor.jpg"));

	}
	public void keyTriggeredActions(){
		Control control= viewer.getControl();
		
		control.addKeyListener(new KeyListener() {
			
			@Override
			public void keyReleased(org.eclipse.swt.events.KeyEvent e) {
				// TODO Auto-generated method stub
				
			}
			
			@Override
			public void keyPressed(org.eclipse.swt.events.KeyEvent e) {
				// TODO Auto-generated method stub
							
				//99 este codul pentru 'c' iar 
				//stateMask este codul pentru CTRL
				
				if ((e.keyCode == 99) && (e.stateMask == 262144) ){
					copyAction.run();
				}
				
			}
		});
	}

	@Override
	public void createPartControl(Composite parent) {
		// TODO Auto-generated method stub

		viewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);

		drillDownAdapter = new DrillDownAdapter(viewer);

		viewer.setContentProvider(new AdaptorContentProvider());
		viewer.setLabelProvider(new AdaptorLabelProvider());
		viewer.setSorter(new AdaptorSorter());
		// viewer.setInput(getInitalInput());
		
		
		viewer.setInput(NamespaceRoot.instance);

		viewer.expandAll();
		
		makeActions();
		hookContextMenu(); // pentru clickDreapta
		contributeToActionBars();
		keyTriggeredActions();


		viewer.addFilter(patternFilter);
		
	}

	@Override
	public void setFocus() {
		// TODO Auto-generated method stub
		viewer.getControl().setFocus();
		
	}
}
